package com.yehebl.orm.data.common.xml;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.yehebl.orm.data.common.IDao;
import com.yehebl.orm.data.common.xml.dto.XmlSql;
import com.yehebl.orm.exception.SqlXmlExpressionException;


/**
 * query xml 默认操作
 *
 */
public class QueryXmlSql extends AQueryXmlSql {

	public QueryXmlSql(String sqlName) {
		super.setSqlName(sqlName);
	}

	public QueryXmlSql() {
	}

	public QueryXmlSql(IDao dao, String sqlName) {
		this.setDao(dao);
		this.setSqlName(sqlName);
	}

	public QueryXmlSql(IDao dao) {
		this.setDao(dao);
	}

	public static QueryXmlSql createQuery() {
		return new QueryXmlSql();
	}


	@Override
	public StringBuilder getResultSql(XmlSql xmlSql, List<Object> list) {
		StringBuilder sb = new StringBuilder();
		if (this.getSql() != null) {
			sb.append(this.getSql());
		} else {
			sb.append(xmlSql.getSql());
		}
		try {
			int oldAppIndex = 0;
			while (true) {
				int paramIndex = sb.indexOf("&", oldAppIndex);
				if (paramIndex == -1) {
					break;
				}
				oldAppIndex = paramIndex + 1;
				int paramsKeyIndex = sb.indexOf(" ", paramIndex);
				int paramsKeyIndex5 = sb.indexOf("\n", paramIndex);
				if (paramsKeyIndex5 < paramsKeyIndex) {
					paramsKeyIndex = paramsKeyIndex5;
				}
				int paramsKeyIndex1 = sb.indexOf("}", paramIndex);
				int paramsKeyIndex2 = sb.indexOf(")", paramIndex);
				int paramsKeyIndex3 = sb.indexOf("(", paramIndex);
				int paramsKeyIndex4 = sb.indexOf("{", paramIndex);
				if (paramsKeyIndex1 != -1 && (paramsKeyIndex == -1 || paramsKeyIndex > paramsKeyIndex1)) {
					paramsKeyIndex = paramsKeyIndex1;
				}
				if (paramsKeyIndex2 != -1 && (paramsKeyIndex == -1 || paramsKeyIndex > paramsKeyIndex2)) {
					paramsKeyIndex = paramsKeyIndex2;
				}
				if (paramsKeyIndex3 != -1 && (paramsKeyIndex == -1 || paramsKeyIndex > paramsKeyIndex3)) {
					paramsKeyIndex = paramsKeyIndex3;
				}
				if (paramsKeyIndex4 != -1 && (paramsKeyIndex == -1 || paramsKeyIndex > paramsKeyIndex4)) {
					paramsKeyIndex = paramsKeyIndex4;
				}
				if (paramsKeyIndex == -1) {
					paramsKeyIndex = sb.length();
				}
				String appKey = sb.substring(paramIndex, paramsKeyIndex).trim();
				String mapKey = appKey.substring(1, appKey.length());
				int startIndex = sb.indexOf(appKey);
				if (super.getAppendSql() != null && super.getAppendSql().containsKey(mapKey)) {
					sb.replace(startIndex, (startIndex + appKey.length()), super.getAppendSql().get(mapKey));
				} else {
					sb.replace(startIndex, (startIndex + appKey.length()), "");
				}
			}

			int oldIndex = 0;
			while (true) {
				int paramIndex = sb.indexOf(":", oldIndex);
				if (paramIndex == -1) {
					break;
				}
				oldIndex = paramIndex + 1;
				int paramsKeyIndex = sb.indexOf(" ", paramIndex);
				int paramsKeyIndex5 = sb.indexOf("\n", paramIndex);
				if(paramsKeyIndex5!=-1){
					if (paramsKeyIndex5 < paramsKeyIndex) {
						paramsKeyIndex = paramsKeyIndex5;
					}
				}
				int paramsKeyIndex1 = sb.indexOf("}", paramIndex);
				int paramsKeyIndex2 = sb.indexOf(")", paramIndex);
				int paramsKeyIndex3 = sb.indexOf("(", paramIndex);
				int paramsKeyIndex4 = sb.indexOf("{", paramIndex);

				if (paramsKeyIndex1 != -1 && (paramsKeyIndex == -1 || paramsKeyIndex > paramsKeyIndex1)) {
					paramsKeyIndex = paramsKeyIndex1;
				}
				if (paramsKeyIndex2 != -1 && (paramsKeyIndex == -1 || paramsKeyIndex > paramsKeyIndex2)) {
					paramsKeyIndex = paramsKeyIndex2;
				}
				if (paramsKeyIndex3 != -1 && (paramsKeyIndex == -1 || paramsKeyIndex > paramsKeyIndex3)) {
					paramsKeyIndex = paramsKeyIndex3;
				}
				if (paramsKeyIndex4 != -1 && (paramsKeyIndex == -1 || paramsKeyIndex > paramsKeyIndex4)) {
					paramsKeyIndex = paramsKeyIndex4;
				}
				if (paramsKeyIndex == -1) {
					paramsKeyIndex = sb.length();
				}
				String paramsKey = sb.substring(paramIndex + 1, paramsKeyIndex).trim();
				if (super.getParams() != null && super.getParams().containsKey(paramsKey)) {
					Object object = super.getParams().get(paramsKey);
					int size = 0;
					if (object instanceof Object[]) {
						Object[] pk = (Object[]) object;
						size = pk.length;
						for (Object object2 : pk) {
							list.add(object2);
						}
					} else if (object instanceof Collection) {
						Collection<?> pk = (Collection<?>) object;
						size = pk.size();
						for (Object object2 : pk) {
							list.add(object2);
						}
					}
					if (size == 0) {
						sb.replace(paramIndex, paramsKeyIndex, "?");
						list.add(super.getParams().get(paramsKey));
					} else {
						StringBuilder sb1 = new StringBuilder();
						for (int i = 0; i < size; i++) {
							if (i < size - 1) {
								sb1.append("?,");
								continue;
							}
							sb1.append("?");
						}
						sb.replace(paramIndex, paramsKeyIndex, sb1.toString());
					}
				}
			}
			Pattern pt1 = Pattern.compile("\\{[\\s\\S\\d\\D\\w\\W][^}]+\\}");
			Matcher matcher1 = pt1.matcher(sb.toString());
			while (matcher1.find()) {
				String paramsStr = matcher1.group(0);
				int startIndex = sb.indexOf(paramsStr);
				boolean flag = true;
				while (true) {
					int paramIndex = paramsStr.indexOf(":");
					if (paramIndex == -1) {
						break;
					}
					flag = false;
					int paramsKeyIndex = paramsStr.indexOf(" ", paramIndex);
					if (paramsKeyIndex == -1) {
						paramsKeyIndex = paramsStr.length() - 1;
					}

					sb.replace(startIndex, (startIndex + paramsStr.length()), "");
					break;
				}
				if (flag) {
					sb.replace(startIndex, (startIndex + paramsStr.length()),
							paramsStr.substring(1, paramsStr.length() - 1));
				}
			}



			if (this.getPrefixSql() != null) {
				sb.insert(0, "select " + this.getPrefixSql().toString() + " ");
			}
		} catch (Exception e) {
			throw new SqlXmlExpressionException("装配xml出错[" + sb.toString() + "]" + e.getMessage());
		}
		return sb;
	}

}
